package com.nidu.demo.security.core;

import cn.hutool.core.map.MapUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.nidu.demo.common.constants.RequestHeaderConstants;
import com.nidu.demo.common.enums.DataScopeEnum;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 登录用户信息
 *
 * @author auto
 */
@Data
@Accessors(chain = true)
public class LoginUser {

    /**
     * 用户编号
     */
    private Long id;
    /**
     * 用户类型
     */
    private Integer userType;
    /**
     * 租户编号
     */
    private Long tenantId;
    /**
     * 授权范围
     */
    private List<String> scopes;

    // ========== 上下文 ==========
    /**
     * 上下文字段，不进行持久化
     *
     * 1. 用于基于 LoginUser 维度的临时缓存
     */
    @JsonIgnore
    private Map<String, Object> context;

    public void setContext(String key, Object value) {
        if (context == null) {
            context = new HashMap<>();
        }
        context.put(key, value);
    }

    public <T> T getContext(String key, Class<T> type) {
        return MapUtil.get(context, key, type);
    }

    public static LoginUser create(Long userId, Integer userType, Long tenantId, List<String> scopes){
        LoginUser loginUser = new LoginUser();
        loginUser.setId(userId)
                .setUserType(userType)
                .setTenantId(tenantId)
                .setScopes(scopes);
        return loginUser;
    }

    /**
     * 设置数据权限信息到context中
     */
    public void setDataPermission(DataScopeEnum dataScope, Set<Long> accessibleDeptIds) {
        setContext(RequestHeaderConstants.CONTEXT_DATA_SCOPE, dataScope);
        setContext(RequestHeaderConstants.CONTEXT_DEPT_IDS, accessibleDeptIds);
    }

    /**
     * 获取数据权限范围
     */
    public DataScopeEnum getDataScope() {
        return getContext(RequestHeaderConstants.CONTEXT_DATA_SCOPE, DataScopeEnum.class);
    }

    /**
     * 获取可访问的部门ID集合
     */
    @SuppressWarnings("unchecked")
    public Set<Long> getDeptIds() {
        return getContext(RequestHeaderConstants.CONTEXT_DEPT_IDS, Set.class);
    }

}
